/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
package GUI;

import LogParser.CommandsHistory;
import Tools.ACommand;
import Tools.CMDThreadGUI;
import Tools.FactorySingletonCommandGUI;
import Tools.IObserverGUI;
import Tools.TModel;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import sun.swing.FilePane;
import java.util.List;
import java.util.Map;

/**
 *
 * @author Иван
 */
public class Form extends JFrame implements IObserverGUI {

    private TModel model;
    private CMDThreadGUI commandThread;
    private CommandsHistory history;
    private String lWorkDirectory,
            rWorkDirectory,
            destinationDirectiry;
    private boolean lActiv,
            rActiv,rUpdate, lUpdate;
    private JPanel buttonsPanel,
            cmdPanel,
            browserPanel,
            lDriversBrowser,
            rDriversBrowser;
    private JScrollPane lScrollPane,
            rScrollPane;
    private JButton bCopy,
            bMove,
            bMkdir,
            bBrowse,
            bDelete,
            bFind,
            bTree,
            bExit;
    private JTextField cmdField;
    private JLabel cmdPuth,
            lBrowserPuth,
            rBrowserPuth,
            lBrowserInfo,
            rBrowserInfo;
    private JMenuBar menuBar;
    private JList lBrowserList,
            rBrowserList;
    private DefaultListModel lListModel,
            rListModel;
    private Map<String, String> lBrowserDirectories = new HashMap<String, String>(0),
            rBrowserDirectories = new HashMap<String, String>(0);

    public Form() {
        setLayout(new GridBagLayout());
        setTitle("My Commander");
        //setSize(Toolkit.getDefaultToolkit().getScreenSize());
        setExtendedState(MAXIMIZED_BOTH);
        setMinimumSize(new Dimension(Toolkit.getDefaultToolkit().getScreenSize()));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        try {
            history = new CommandsHistory("app.log");

            model = TModel.getInstance();
            model.setInitCommandFactory(new FactorySingletonCommandGUI());
        } catch (Exception e) {
        }

        //workDirectory = new String();

        lWorkDirectory = new String();
        rWorkDirectory = new String();

        lScrollPane = new JScrollPane();
        rScrollPane = new JScrollPane();

        buttonsPanel = new JPanel();
        buttonsPanel.setBackground(Color.red);

        cmdPanel = new JPanel();
        cmdPanel.setBackground(Color.green);

        browserPanel = new JPanel(new GridBagLayout());

    }

    private void initButtonsPanel() {

        bCopy = new JButton("Copy");
        bCopy.setSize(60, 20);
        bCopy.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int i;
                String file = "";

                if (!lActiv) {
                    destinationDirectiry = lWorkDirectory;

                    i = rBrowserList.getSelectedIndex();
                    file = (String) rListModel.get(i);
                    rUpdate = true;

                } else if (!rActiv) {
                    destinationDirectiry = rWorkDirectory;

                    i = lBrowserList.getSelectedIndex();
                    file = (String) lListModel.get(i);
                    lUpdate = true;
                }


                commandThread = new CMDThreadGUI("copy " + file + " " + destinationDirectiry, getObserver());
            }
        });

        bBrowse = new JButton("Browse");
        bBrowse.setSize(60, 20);

        bMkdir = new JButton("Mkdir");
        bMkdir.setSize(60, 20);

        bExit = new JButton("Exit");
        bExit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        bExit.setSize(60, 20);

        bMove = new JButton("Move");
        bMove.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int i;
                String file = "";
                // update = true;
                if (!lActiv) {
                    destinationDirectiry = lWorkDirectory;

                    i = rBrowserList.getSelectedIndex();
                    file = (String) rListModel.get(i);

                } else if (!rActiv) {
                    destinationDirectiry = rWorkDirectory;

                    i = lBrowserList.getSelectedIndex();
                    file = (String) lListModel.get(i);

                }


                commandThread = new CMDThreadGUI("move " + file + " " + destinationDirectiry, getObserver());
            }
        });
        bMove.setSize(60, 20);

        bDelete = new JButton("Delete");
        bDelete.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int i;
                String file = "";
                //      update = true;
                if (!lActiv) {

                    lUpdate = true;
                    i = rBrowserList.getSelectedIndex();
                    file = (String) rListModel.get(i);

                } else if (!rActiv) {

                    rUpdate = true;
                    i = lBrowserList.getSelectedIndex();
                    file = (String) lListModel.get(i);

                }


                commandThread = new CMDThreadGUI("del " + file, getObserver());

            }
        });
        bDelete.setSize(60, 20);

        bTree = new JButton("Tree");
        bTree.setSize(60, 20);

        bFind = new JButton("Find");
        bFind.setSize(60, 20);

        buttonsPanel.add(bBrowse, JPanel.LEFT_ALIGNMENT);
        buttonsPanel.add(bFind, JPanel.LEFT_ALIGNMENT);
        buttonsPanel.add(bTree, JPanel.LEFT_ALIGNMENT);
        buttonsPanel.add(bCopy, JPanel.LEFT_ALIGNMENT);
        buttonsPanel.add(bMove, JPanel.LEFT_ALIGNMENT);
        buttonsPanel.add(bDelete, JPanel.LEFT_ALIGNMENT);
        buttonsPanel.add(bMkdir, JPanel.LEFT_ALIGNMENT);
        buttonsPanel.add(bExit, JPanel.LEFT_ALIGNMENT);

    }

    private void initMenuBar() {

        menuBar = new JMenuBar();

        JMenu file = new JMenu("File");

        JMenuItem fileExit = new JMenuItem("Exit");

        fileExit.setToolTipText("Exit application");
        fileExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,
                ActionEvent.CTRL_MASK));

        fileExit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent event) {
                System.exit(0);
            }
        });



        file.addSeparator();
        file.add(fileExit);

        menuBar.add(file);

        setJMenuBar(menuBar);


        setTitle("Submenu");
        setSize(360, 250);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    private void initDrivers() {
        lDriversBrowser = new JPanel();
        lDriversBrowser.setBackground(Color.BLUE);

        lDriversBrowser.add(new JButton("c"));
        lDriversBrowser.add(new JButton("d"));
        lDriversBrowser.add(new JButton("e"));
        lDriversBrowser.add(new JButton("f"));

        rDriversBrowser = new JPanel();
        rDriversBrowser.setBackground(Color.BLUE);

        rDriversBrowser.add(new JButton("c"));
        rDriversBrowser.add(new JButton("d"));
        rDriversBrowser.add(new JButton("e"));
        rDriversBrowser.add(new JButton("f"));
    }

    private void initBrowsers() {

        initDrivers();

        lListModel = new DefaultListModel();
        lBrowserList = new JList(lListModel);
        lBrowserList.setLayoutOrientation(JList.VERTICAL);
        
        lScrollPane.setViewportView(lBrowserList);
        lScrollPane.setPreferredSize(new Dimension(500, 400));

        lBrowserList.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {
                lActiv = true;
                rActiv = false;
                commandThread = new CMDThreadGUI("cd " + lWorkDirectory, getObserver());

                try {
                    commandThread.t.join();
                } catch (InterruptedException ex) {
                    JOptionPane.showConfirmDialog(getRootPane(), ex.getMessage(), "Error", JOptionPane.ERROR, JOptionPane.ERROR_MESSAGE);
                }

                if ((e.getClickCount() == 2)) {

                    int i = lBrowserList.getSelectedIndex();
                    lWorkDirectory = (String) lListModel.get(i);
                    commandThread = new CMDThreadGUI("cd " + lWorkDirectory, getObserver());

                    try {
                        commandThread.t.join();
                    } catch (InterruptedException ex) {
                        JOptionPane.showConfirmDialog(getRootPane(), ex.getMessage(), "Error", JOptionPane.ERROR, JOptionPane.ERROR_MESSAGE);
                    }

                }

            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });

        rListModel = new DefaultListModel();
        rBrowserList = new JList(rListModel);
        rBrowserList.setLayoutOrientation(JList.VERTICAL);

        rScrollPane.setViewportView(rBrowserList);
        rScrollPane.setPreferredSize(new Dimension(500, 400));

        rBrowserList.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {
                lActiv = false;
                rActiv = true;
                commandThread = new CMDThreadGUI("cd " + rWorkDirectory, getObserver());

                try {
                    commandThread.t.join();
                } catch (InterruptedException ex) {
                    JOptionPane.showConfirmDialog(getRootPane(), ex.getMessage(), "Error", JOptionPane.ERROR, JOptionPane.ERROR_MESSAGE);
                }


                if ((e.getClickCount() == 2)) {

                    int i = rBrowserList.getSelectedIndex();
                    rWorkDirectory = (String) rListModel.get(i);
                    commandThread = new CMDThreadGUI("cd " + rWorkDirectory, getObserver());

                    try {
                        commandThread.t.join();
                    } catch (InterruptedException ex) {
                        JOptionPane.showConfirmDialog(getRootPane(), ex.getMessage(), "Error", JOptionPane.ERROR, JOptionPane.ERROR_MESSAGE);
                    }

                    // rWorkDirectory = model.getWorkDirectory();
                    // commandThread = new CMDThreadGUI("dir", getObserver());

                    // try {
                    //     commandThread.t.join();
                    //  } catch (InterruptedException ex) {
                    //     JOptionPane.showConfirmDialog(getRootPane(), ex.getMessage(), "Error", JOptionPane.ERROR, JOptionPane.ERROR_MESSAGE);
                    //  }

                }

            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });

        lBrowserPuth = new JLabel();
        rBrowserPuth = new JLabel();

        lWorkDirectory = model.getWorkDirectory();
        rWorkDirectory = model.getWorkDirectory();

        lBrowserInfo = new JLabel("info");
        rBrowserInfo = new JLabel("info");

        GridBagConstraints c = new GridBagConstraints();

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 0;
        c.insets.set(0, 10, 10, 10);
        browserPanel.add(lDriversBrowser, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 0;
        c.insets.set(0, 10, 10, 10);
        browserPanel.add(rDriversBrowser, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1;
        c.insets.set(0, 10, 0, 10);
        browserPanel.add(lBrowserPuth, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 1;
        c.insets.set(0, 10, 0, 10);
        browserPanel.add(rBrowserPuth, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 2;
        c.insets.set(10, 10, 10, 10);
        browserPanel.add(lScrollPane, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 2;
        c.insets.set(10, 10, 10, 10);
        browserPanel.add(rScrollPane, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 3;
        c.insets.set(0, 10, 10, 10);
        browserPanel.add(lBrowserInfo, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 3;
        c.insets.set(0, 10, 10, 10);
        browserPanel.add(rBrowserInfo, c);


    }

    private void initCMDPanel() {
        cmdField = new JTextField();
        cmdField.setPreferredSize(new Dimension(300, 20));

        cmdField.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_UP) {
                    try {
                        String s = history.back();
                        if (!"".equals(s)) {
                            cmdField.setText(s);
                        }
                    } catch (Exception ex) {
                        JOptionPane.showConfirmDialog(getRootPane(), ex.getMessage(), "Error", JOptionPane.ERROR, JOptionPane.ERROR_MESSAGE);
                    }

                } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                    try {
                        String s = history.next();
                        if (!"".equals(s)) {
                            cmdField.setText(s);
                        }

                    } catch (Exception ex) {
                        JOptionPane.showConfirmDialog(getRootPane(), ex.getMessage(), "Error", JOptionPane.ERROR, JOptionPane.ERROR_MESSAGE);
                    }

                } else if (e.getKeyCode() == KeyEvent.VK_ENTER) {

                    if (lActiv) {
                        lUpdate = true; 
                    } else if (rActiv) {                       
                        rUpdate = true;
                    }

                    commandThread = new CMDThreadGUI(cmdField.getText(), getObserver());
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
            }
        });

        cmdPuth = new JLabel(model.getWorkDirectory());

        cmdPanel.add(cmdPuth);
        cmdPanel.add(cmdField);
    }

    private void initGUI() {
        initMenuBar();
        initBrowsers();
        initCMDPanel();
        initButtonsPanel();

        GridBagConstraints c = new GridBagConstraints();

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 0;
        add(browserPanel, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1;
        c.insets.set(5, 0, 5, 0);
        add(cmdPanel, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 2;
        add(buttonsPanel, c);

        lActiv = true;
        rActiv = false;
        commandThread = new CMDThreadGUI("cd " + model.getWorkDirectory(), getObserver());

    }

    private void start() {
        setVisible(true);
    }

    @Override
    public void updateView(String processedCommand, List<String> parameters) {
   
        if ("dir".equals(processedCommand)) {
            updateBrowser(parameters);
        } else {
            updateCMD();
            try {

                if (lActiv) {
                    lWorkDirectory = model.getWorkDirectory();
                } else if (rActiv) {
                    rWorkDirectory = model.getWorkDirectory();
                }
                
                commandThread = new CMDThreadGUI("dir", getObserver());
                commandThread.t.join();
                
            } catch (InterruptedException ex) {
                JOptionPane.showConfirmDialog(getRootPane(), ex.getMessage(), "Error", JOptionPane.ERROR, JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void updateBrowser(List<String> parameters) {
        String[] tmp;
        if (!lWorkDirectory.equals(lBrowserPuth.getText()) || lUpdate) {

            lBrowserPuth.setText(lWorkDirectory);
            lListModel.clear();
            lBrowserDirectories.clear();
            for (String str : parameters) {
                tmp = str.split("\\s", 2);

                lListModel.addElement(tmp[0]);
                lBrowserDirectories.put(tmp[0], tmp[1]);
            }
            lUpdate = false;
        }

        if (!rWorkDirectory.equals(rBrowserPuth.getText()) || rUpdate) {
            rBrowserPuth.setText(rWorkDirectory);
            rListModel.clear();
            rBrowserDirectories.clear();
            for (String str : parameters) {
                tmp = str.split("\\s", 2);

                rListModel.addElement(tmp[0]);
                rBrowserDirectories.put(tmp[0], tmp[1]);
            }
            rUpdate = false;
        }
       
    }

    private void updateCMD() {
        cmdPuth.setText(model.getWorkDirectory());
        cmdField.setText("");
    }

    private IObserverGUI getObserver() {
        return this;
    }

    public static void main(String[] arg) {


        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Form gui = new Form();
                gui.initGUI();
                gui.start();
            }
        });
    }
}
